home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 April: Mac OS SDK / Dev.CD Apr 96 SDK / Dev.CD Apr 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc / Sample Code / Sample Editors⁄Viewers / Draw Editor / Source / SampleCollections.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-11  |  15.1 KB  |  790 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        Collections.cpp
  3.  
  4.     Contains:    Sample collection functions & classes
  5.  
  6.     Written by:    Steve Smith
  7.  
  8.     Copyright:    © 1995 by Apple Computer, Inc., all rights reserved.
  9.  
  10.     Description:
  11.                 CList: Generic unordered list
  12.                 COrderedList: Generic ordered list
  13.                 CFrameList: Unordered list of frames -
  14.                             frames automatically refcounted when 
  15.                             added/removed from list.
  16.                 CQueue: Generic queue collection
  17.                 CStack: Generic stack collection
  18. */
  19.  
  20.  
  21. #ifndef _SAMPLECOLLECTIONS_
  22. #include "SampleCollections.h"
  23. #endif
  24.  
  25. // --- OpenDoc Includes ---
  26.  
  27. #ifndef _ODTYPES_
  28. #include <ODTypes.h>
  29. #endif
  30.  
  31. #ifndef SOM_ODFrame_xh
  32. #include <Frame.xh>
  33. #endif
  34.  
  35. // --- OpenDoc Utilities ---
  36.  
  37. #ifndef _EXCEPT_
  38. #include <Except.h>
  39. #endif
  40.  
  41. #ifndef _ODNEW_
  42. #include <ODNew.h>
  43. #endif
  44.  
  45. #ifndef _LINKLIST_
  46. #include <LinkList.h>
  47. #endif
  48.  
  49. #ifndef _LIMITS_
  50. #include <Limits.h>
  51. #endif
  52.  
  53. #ifndef _ODUTILS_
  54. #include <ODUtils.h>
  55. #endif
  56.  
  57.  
  58. //====================================================================
  59. // CGenericLink
  60. //====================================================================
  61.  
  62. CGenericLink::CGenericLink()
  63.     :Link()
  64. {
  65.     fValue = kODNULL;
  66. }
  67.  
  68. CGenericLink::CGenericLink(void* value)
  69.     :Link()
  70. {
  71.     fValue = value;
  72. }
  73.  
  74. CGenericLink::~CGenericLink()
  75. {
  76. }
  77.  
  78. void* CGenericLink::GetValue()
  79. {
  80.     return fValue;
  81. }
  82.  
  83. void CGenericLink::SetValue(void* value)
  84. {
  85.     fValue = value;
  86. }
  87.  
  88. //====================================================================
  89. // CFrameLink
  90. //====================================================================
  91.  
  92. CFrameLink::CFrameLink()
  93.     :CGenericLink()
  94. {
  95. }
  96.  
  97. CFrameLink::CFrameLink(ODFrame* frame)
  98.     :CGenericLink()
  99. {
  100.     Environment* ev = somGetGlobalEnvironment();
  101.     frame->Acquire(ev);
  102.     fValue = (void*)frame;
  103. }
  104.  
  105. CFrameLink::~CFrameLink()
  106. {
  107.     if ( fValue ) {
  108.         Environment* ev = somGetGlobalEnvironment();
  109.         ((ODFrame*)fValue)->Release(ev);
  110.     }
  111. }
  112.  
  113. ODFrame* CFrameLink::GetFrame()
  114. {
  115.     return ((ODFrame*)fValue);
  116. }
  117.  
  118. void CFrameLink::SetFrame(ODFrame* frame)
  119. {
  120.     Environment* ev = somGetGlobalEnvironment();
  121.  
  122.     if ( fValue ) ((ODFrame*)fValue)->Release(ev);
  123.     if ( frame ) frame->Acquire(ev);
  124.     
  125.     fValue = (void*)frame;
  126. }
  127.  
  128. //====================================================================
  129. // CList
  130. //====================================================================
  131.  
  132. CList::CList()
  133. {
  134. }
  135.  
  136. CList::~CList()
  137. {
  138.     fList.DeleteAllLinks();
  139. }
  140.  
  141. ODBoolean CList::IsEmpty() const
  142. {
  143.     return fList.IsEmpty();
  144. }
  145.  
  146. ODULong CList::Count() const
  147. {
  148.     return fList.Count();
  149. }
  150.  
  151. ODBoolean CList::Contains(const void* value)
  152. {
  153.     if ( fList.IsEmpty() ) return kODFalse;
  154.     
  155.     LinkedListIterator    iter(&fList);
  156.     for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
  157.     {
  158.         if ( ((CGenericLink*)link)->GetValue() == value )
  159.             return kODTrue;
  160.     }
  161.  
  162.     return kODFalse;
  163. }
  164.  
  165. void CList::DeleteAllLinks()
  166. {
  167.     LinkedListIterator    iter(&fList);
  168.     for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
  169.     {
  170.         delete (((CGenericLink*)link)->GetValue());
  171.     }
  172.     fList.RemoveAll();
  173. }
  174.  
  175. void CList::RemoveAllLinks()
  176. {
  177.     fList.RemoveAll();
  178. }
  179.  
  180. void CList::Delete(void* value)
  181. {
  182.     LinkedListIterator    iter(&fList);
  183.     for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
  184.     {
  185.         if ( ((CGenericLink*)link)->GetValue() == value )
  186.         {
  187.             delete (((CGenericLink*)link)->GetValue());
  188.             fList.Remove(*link);
  189.             return;
  190.         }
  191.     }
  192. }
  193.  
  194. void CList::Remove(void* value)
  195. {
  196.     LinkedListIterator    iter(&fList);
  197.     for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
  198.     {
  199.         if ( ((CGenericLink*)link)->GetValue() == value )
  200.         {
  201.             fList.Remove(*link);
  202.             return;
  203.         }
  204.     }
  205. }
  206.  
  207. void CList::Add(void* value)
  208. {
  209.     CGenericLink* link = new CGenericLink(value);
  210.     fList.AddLast(link);
  211. }
  212.  
  213.  
  214. //====================================================================
  215. // CListIterator
  216. //====================================================================
  217.  
  218. CListIterator::CListIterator(CList* list)
  219. {
  220.     fIter = new LinkedListIterator(&list->fList);
  221. }
  222.  
  223. CListIterator::~CListIterator()
  224. {
  225.     delete fIter;
  226. }
  227.     
  228. void* CListIterator::First()
  229. {
  230.     CGenericLink* link = (CGenericLink*) fIter->First();
  231.  
  232.     //$$$$$ for empty list, link will be null
  233.     return (void*) link ? link->GetValue() : kODNULL;
  234. }
  235.  
  236. void* CListIterator::Next()
  237. {
  238.     CGenericLink* link = (CGenericLink*) fIter->Next();
  239.     
  240.     //$$$$$ At end of list, link will be null
  241.     return (void*) link ? link->GetValue() : kODNULL;
  242. }
  243.  
  244. void* CListIterator::Previous()
  245. {
  246.     CGenericLink* link = (CGenericLink*) fIter->Previous();
  247.     
  248.     //$$$$$ At head of list, link will be null
  249.     return (void*) link ? link->GetValue() : kODNULL;
  250. }
  251.  
  252. void* CListIterator::Last()
  253. {
  254.     CGenericLink* link = (CGenericLink*) fIter->Last();
  255.  
  256.     //$$$$$ for empty list, link will be null
  257.     return (void*) link ? link->GetValue() : kODNULL;
  258. }
  259.  
  260. void* CListIterator::Current()
  261. {
  262.     CGenericLink* link = (CGenericLink*) fIter->Current();
  263.  
  264.     //$$$$$ for empty list, link will be null
  265.     return (void*) link ? link->GetValue() : kODNULL;
  266. }
  267.  
  268. ODBoolean CListIterator::IsNotComplete()
  269. {
  270.     return fIter->IsNotComplete();
  271. }
  272.  
  273. void CListIterator::RemoveCurrent()
  274. {
  275.     fIter->RemoveCurrent();
  276. }
  277.  
  278. void CListIterator::DeleteCurrent()
  279. {
  280.     CGenericLink* link = (CGenericLink*) fIter->Current();
  281.     fIter->RemoveCurrent();
  282.     
  283.     //$$$$$ for empty list, link is null
  284.     if (link)
  285.         delete link->GetValue();
  286.         
  287.     delete link;
  288. }
  289.  
  290. //====================================================================
  291. // COrderedList
  292. //====================================================================
  293.  
  294. COrderedList::COrderedList()
  295. {
  296. }
  297.  
  298. COrderedList::~COrderedList()
  299. {
  300.     fList.DeleteAllLinks();
  301. }
  302.  
  303. COrderedList::COrderedList(COrderedList *list)
  304. {
  305.     // (MH)  Copy constructor for COrderedList
  306.     COrdListIterator iter(list);
  307.     for (void* elem = iter.First(); iter.IsNotComplete(); elem = iter.Next())
  308.     {
  309.         this->AddLast(elem);
  310.     }
  311. }
  312.  
  313. ODBoolean COrderedList::IsEmpty() const
  314. {
  315.     return fList.IsEmpty();
  316. }
  317.  
  318. ODULong COrderedList::Count() const
  319. {
  320.     return fList.Count();
  321. }
  322.  
  323. ODBoolean COrderedList::Contains(const void* value)
  324. {
  325.     if ( fList.IsEmpty() ) return kODFalse;
  326.     
  327.     LinkedListIterator    iter(&fList);
  328.     for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
  329.     {
  330.         if ( ((CGenericLink*)link)->GetValue() == value )
  331.             return kODTrue;
  332.     }
  333.  
  334.     return kODFalse;
  335. }
  336.  
  337. ODUShort COrderedList::Position(const void* value)
  338. {
  339.     if ( fList.IsEmpty() ) return kListIsEmpty;
  340.     
  341.     ODUShort position = 0;
  342.     LinkedListIterator    iter(&fList);
  343.     for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
  344.     {
  345.         position++;
  346.         if ( ((CGenericLink*)link)->GetValue() == value )
  347.             return kODTrue;
  348.     }
  349.  
  350.     return kItemNotFound;
  351. }
  352.  
  353. void COrderedList::DeleteAllLinks()
  354. {
  355.     LinkedListIterator    iter(&fList);
  356.     for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
  357.     {
  358.         delete (((CGenericLink*)link)->GetValue());
  359.     }
  360.     fList.RemoveAll();
  361. }
  362.  
  363. void COrderedList::RemoveAllLinks()
  364. {
  365.     fList.RemoveAll();
  366. }
  367.  
  368. void COrderedList::Delete(void* value)
  369. {
  370.     LinkedListIterator    iter(&fList);
  371.     for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
  372.     {
  373.         if ( ((CGenericLink*)link)->GetValue() == value )
  374.         {
  375.             delete (((CGenericLink*)link)->GetValue());
  376.             fList.Remove(*link);
  377.             return;
  378.         }
  379.     }
  380. }
  381.  
  382. void COrderedList::Remove(void* value)
  383. {
  384.     LinkedListIterator    iter(&fList);
  385.     for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
  386.     {
  387.         if ( ((CGenericLink*)link)->GetValue() == value )
  388.         {
  389.             fList.Remove(*link);
  390.             return;
  391.         }
  392.     }
  393. }
  394.  
  395. void* COrderedList::RemoveFirst()
  396. {
  397.     CGenericLink* link = (CGenericLink*) fList.RemoveFirst();
  398.     return link ? (void*) link->GetValue() : (void*)kODNULL;
  399. }
  400.  
  401. void* COrderedList::RemoveLast()
  402. {
  403.     CGenericLink* link = (CGenericLink*) fList.RemoveLast();
  404.     return link ? (void*) link->GetValue() : (void*)kODNULL;
  405. }
  406.  
  407. void COrderedList::AddBefore(const void* existing, void* value)
  408. {
  409.     LinkedListIterator    iter(&fList);
  410.     for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
  411.     {
  412.         if ( ((CGenericLink*)link)->GetValue() == existing )
  413.         {
  414.             CGenericLink* newLink = new CGenericLink(value);
  415.             fList.AddBefore(*link,newLink);
  416.             return;
  417.         }
  418.     }
  419. }
  420.  
  421. void COrderedList::AddAfter(const void* existing, void* value)
  422. {
  423.     LinkedListIterator    iter(&fList);
  424.     for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
  425.     {
  426.         if ( ((CGenericLink*)link)->GetValue() == existing )
  427.         {
  428.             CGenericLink* newLink = new CGenericLink(value);
  429.             fList.AddAfter(*link,newLink);
  430.             return;
  431.         }
  432.     }
  433. }
  434.  
  435. void COrderedList::AddFirst(void* value)
  436. {
  437.     CGenericLink* link = new CGenericLink(value);
  438.     fList.AddFirst(link);
  439. }
  440.  
  441. void COrderedList::AddLast(void* value)
  442. {
  443.     CGenericLink* link = new CGenericLink(value);
  444.     fList.AddLast(link);
  445. }
  446.  
  447. void* COrderedList::After(const void* value) const
  448. {
  449.     LinkedListIterator    iter((LinkedList*)&fList);
  450.     for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
  451.     {
  452.         if ( ((CGenericLink*)link)->GetValue() == value )
  453.         {
  454.             Link* after = fList.After(*link);
  455.             // $$$$$ After may be null, if matched element was at end of list!
  456.             return (void*) after ? ((CGenericLink*)after)->GetValue() : kODNULL;
  457.         }
  458.     }
  459.     return kODNULL;
  460. }
  461.  
  462. void* COrderedList::Before(const void* value) const
  463. {
  464.     LinkedListIterator    iter((LinkedList*)&fList);
  465.     for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
  466.     {
  467.         if ( ((CGenericLink*)link)->GetValue() == value )
  468.         {
  469.             //$$$$$ it would be nice to call the previous link 'before', not 'after'
  470.             Link* before = fList.Before(*link);
  471.             // $$$$$ before may be null, if matched element was at head of list!
  472.             return (void*) before ? ((CGenericLink*)before)->GetValue() : kODNULL;
  473.         }
  474.     }
  475.     return kODNULL;
  476. }
  477.  
  478. void* COrderedList::First() const
  479. {
  480.     CGenericLink* link = (CGenericLink*) fList.First();
  481.     
  482.     //$$$$$ (MH) More empty list problems fixed
  483.     return (void*) link ? link->GetValue() : kODNULL;
  484. }
  485.  
  486. void* COrderedList::Last() const
  487. {
  488.     CGenericLink* link = (CGenericLink*) fList.Last();
  489.     
  490.     //$$$$$ (MH) More empty list problems fixed
  491.     return (void*) link ? link->GetValue() : kODNULL;
  492. }
  493.  
  494. //====================================================================
  495. // COrdListIterator
  496. //====================================================================
  497.  
  498. COrdListIterator::COrdListIterator(COrderedList* list)
  499. {
  500.     fIter = new LinkedListIterator(&list->fList);
  501. }
  502.  
  503. COrdListIterator::~COrdListIterator()
  504. {
  505. }
  506.     
  507.  
  508. //====================================================================
  509. // CFrameList
  510. //====================================================================
  511.  
  512. CFrameList::CFrameList()
  513. {
  514. }
  515.  
  516. CFrameList::~CFrameList()
  517. {
  518.     Environment* ev = somGetGlobalEnvironment();
  519.     
  520.     LinkedListIterator    iter(&fList);
  521.     for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
  522.     {
  523. //        ((CFrameLink*)link)->GetFrame()->Release(ev);
  524.         iter.RemoveCurrent();
  525.         delete link;
  526.     }
  527. }
  528.  
  529. ODBoolean CFrameList::IsEmpty() const
  530. {
  531.     return fList.IsEmpty();
  532. }
  533.  
  534. ODULong CFrameList::Count() const
  535. {
  536.     return fList.Count();
  537. }
  538.  
  539. ODBoolean CFrameList::Contains(const ODFrame* frame)
  540. {
  541.     if ( fList.IsEmpty() ) return kODFalse;
  542.     
  543.     Environment* ev = somGetGlobalEnvironment();
  544.  
  545.     LinkedListIterator    iter(&fList);
  546.     for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
  547.     {
  548.         if ( ODObjectsAreEqual(ev, ((CFrameLink*)link)->GetFrame(), (ODFrame*)frame) )
  549.             return kODTrue;
  550.     }
  551.  
  552.     return kODFalse;
  553. }
  554.  
  555. void CFrameList::Remove(ODFrame* frame)
  556. {
  557.     Environment* ev = somGetGlobalEnvironment();
  558.  
  559.     Link* link = kODNULL;
  560.     LinkedListIterator    iter(&fList);
  561.     for (link=iter.First();iter.IsNotComplete();link=iter.Next())
  562.     {
  563.         if ( ODObjectsAreEqual(ev, ((CFrameLink*)link)->GetFrame(), frame) )
  564.         {
  565. //            frame->Release(ev);
  566. //            iter.RemoveCurrent();
  567. //            delete link;
  568.             break;
  569.         }
  570.     }
  571.     
  572.     if ( link )
  573.     {
  574.         fList.Remove(*link);
  575.         delete link;
  576.     }
  577.     else
  578.         THROW(kODErrInvalidFrame);
  579. }
  580.  
  581. void CFrameList::Add(ODFrame* frame)
  582. {
  583.     CFrameLink* link = new CFrameLink(frame);
  584.     fList.AddLast(link);
  585. }
  586.  
  587. ODFrame* CFrameList::GetFrame()
  588. {
  589.     CFrameLink* link = (CFrameLink*) fList.First();
  590.     return link->GetFrame();
  591. }
  592.  
  593. //====================================================================
  594. // CFrameListIterator
  595. //====================================================================
  596.  
  597. CFrameListIterator::CFrameListIterator(CFrameList* list)
  598. {
  599.     fIter = new LinkedListIterator(&list->fList);
  600. }
  601.  
  602. CFrameListIterator::~CFrameListIterator()
  603. {
  604.     delete fIter;
  605. }
  606.     
  607. ODFrame* CFrameListIterator::First()
  608. {
  609.     CFrameLink* link = (CFrameLink*) fIter->First();
  610.     return link->GetFrame();
  611. }
  612.  
  613. ODFrame* CFrameListIterator::Next()
  614. {
  615.     CFrameLink* link = (CFrameLink*) fIter->Next();
  616.     return link->GetFrame();
  617. }
  618.  
  619. ODFrame* CFrameListIterator::Previous()
  620. {
  621.     CFrameLink* link = (CFrameLink*) fIter->Previous();
  622.     return link->GetFrame();
  623. }
  624.  
  625. ODFrame* CFrameListIterator::Last()
  626. {
  627.     CFrameLink* link = (CFrameLink*) fIter->Last();
  628.     return link->GetFrame();
  629. }
  630.  
  631. ODFrame* CFrameListIterator::Current()
  632. {
  633.     CFrameLink* link = (CFrameLink*) fIter->Current();
  634.     return link->GetFrame();
  635. }
  636.  
  637. ODBoolean CFrameListIterator::IsNotComplete()
  638. {
  639.     return fIter->IsNotComplete();
  640. }
  641.  
  642. void CFrameListIterator::ReleaseCurrent()
  643. {
  644.     Environment* ev = somGetGlobalEnvironment();
  645.  
  646.     CFrameLink* link = (CFrameLink*) fIter->Current();
  647.     link->GetFrame()->Release(ev);
  648.     fIter->RemoveCurrent();
  649. }
  650.  
  651. //====================================================================
  652. // CStack
  653. //====================================================================
  654.  
  655. CStack::CStack()
  656. {
  657.     fMaxDepth = USHRT_MAX;
  658. }
  659.  
  660. CStack::~CStack()
  661. {
  662.     fStack.DeleteAllLinks();
  663. }
  664.  
  665. ODBoolean CStack::IsEmpty()
  666. {
  667.     return fStack.IsEmpty();
  668. }
  669.  
  670. void CStack::EmptyStack(ODBoolean deleteEntries)
  671. {
  672.     if ( deleteEntries )
  673.     {
  674.         LinkedListIterator    iter(&fStack);
  675.         for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
  676.         {
  677.             delete (((CGenericLink*)link)->GetValue());
  678.             fStack.Remove(*link);
  679.         }
  680.     }
  681.     else
  682.         fStack.DeleteAllLinks();
  683. }
  684.  
  685. ODUShort CStack::SetSize(ODUShort maxDepth)
  686. {
  687.     ODULong curSize = fStack.Count();
  688.     
  689.     if ( curSize > maxDepth )
  690.         fMaxDepth = (ODUShort) curSize;
  691.     else
  692.         fMaxDepth = maxDepth;
  693.     
  694.     return fMaxDepth;
  695. }
  696.  
  697. ODBoolean CStack::PushEntry(void* entry)
  698. {
  699.     if ( (ODUShort)fStack.Count() < fMaxDepth )
  700.     {
  701.         CGenericLink* link = new CGenericLink(entry);
  702.         fStack.AddFirst(link);
  703.         return kODTrue;
  704.     }
  705.     else
  706.         return kODFalse;
  707. }
  708.  
  709. void* CStack::PopEntry()
  710. {
  711.     if ( fStack.IsEmpty() )
  712.         return kODNULL;
  713.     else
  714.     {
  715.         CGenericLink* link = (CGenericLink*)fStack.RemoveFirst();
  716.         return link->GetValue();
  717.     }
  718. }
  719.  
  720.  
  721. //====================================================================
  722. // CQueue
  723. //====================================================================
  724.  
  725. CQueue::CQueue()
  726. {
  727.     fMaxEntries = USHRT_MAX;
  728. }
  729.  
  730. CQueue::~CQueue()
  731. {
  732.     fQueue.DeleteAllLinks();
  733. }
  734.  
  735. ODBoolean CQueue::IsEmpty()
  736. {
  737.     return fQueue.IsEmpty();
  738. }
  739.  
  740. void CQueue::EmptyQueue(ODBoolean deleteEntries)
  741. {
  742.     if ( deleteEntries )
  743.     {
  744.         LinkedListIterator    iter(&fQueue);
  745.         for (Link* link=iter.First();iter.IsNotComplete();link=iter.Next())
  746.         {
  747.             delete (((CGenericLink*)link)->GetValue());
  748.             fQueue.Remove(*link);
  749.         }
  750.     }
  751.     else
  752.         fQueue.DeleteAllLinks();
  753. }
  754.  
  755. ODUShort CQueue::SetSize(ODUShort maxEntries)
  756. {
  757.     ODULong curSize = fQueue.Count();
  758.     
  759.     if ( curSize > maxEntries )
  760.         fMaxEntries = (ODUShort) curSize;
  761.     else
  762.         fMaxEntries = maxEntries;
  763.     
  764.     return fMaxEntries;
  765. }
  766.  
  767. ODBoolean CQueue::AddEntry(void* entry)
  768. {
  769.     if ( (ODUShort)fQueue.Count() < fMaxEntries )
  770.     {
  771.         CGenericLink* link = new CGenericLink(entry);
  772.         fQueue.AddLast(link);
  773.         return kODTrue;
  774.     }
  775.     else
  776.         return kODFalse;
  777. }
  778.  
  779. void* CQueue::GetEntry()
  780. {
  781.     if ( fQueue.IsEmpty() )
  782.         return kODNULL;
  783.     else
  784.     {
  785.         CGenericLink* link = (CGenericLink*)fQueue.RemoveFirst();
  786.         return link->GetValue();
  787.     }
  788. }
  789.  
  790.